﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestConsoleApp
{
    public class TestCAS
    {
        public static void Test()
        {
            var cl = new TestCAS();
            Stopwatch watch = Stopwatch.StartNew();
            Parallel.For(0, 50000, i => cl.AppendCAS('a'));
            var time = watch.Elapsed;
            Console.WriteLine(time.TotalMilliseconds);
            watch.Stop();

            watch.Start();
            Parallel.For(0, 50000, i => cl.AppendLock('a'));
            time = watch.Elapsed;
            Console.WriteLine(time.TotalMilliseconds);
            watch.Stop();

            Console.WriteLine("isEqual:" + cl._str.Equals(cl._str1));
        }


        public string _str = "";
        public void AppendCAS(char value)
        {
            var spin = new SpinWait();
            while (true)
            {
                var original = Interlocked.CompareExchange(ref _str, null, null);

                var newString = original + value;
                if (Interlocked.CompareExchange(ref _str, newString, original) == original)
                    break;
                spin.SpinOnce();
            }
        }


        public string _str1 = "";

        private object lk = new object();
        public void AppendLock(char value)
        {
            lock (lk)
            {
                _str1 += value;
            }
        }
    }
}
